<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Grainy Noise Effect</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            overflow: hidden;
        }
        canvas {
            height: 100vh;
            display: block;
        }
    </style>
</head>
<body>
    <canvas id="canvas"></canvas>
    <script>
        window.onload = function() {
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');

    // 设置画布大小与窗口大小一致
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    // 创建像素数据
    const pixels = ctx.createImageData(canvas.width, canvas.height);

    // 填充像素数据
    for (let i = 0, n = pixels.data.length; i < n; i += 4) {
        // 设置像素的 RGBA 值
        const value = Math.floor(Math.random() * 60); // 0-59 之间的随机值
        pixels.data[i]     = value; // 红色
        pixels.data[i + 1] = value; // 绿色
        pixels.data[i + 2] = value; // 蓝色
        pixels.data[i + 3] = 255;   // Alpha 值 (完全不透明)
    }

    // 将像素数据绘制到画布上
    ctx.putImageData(pixels, 0, 0);

    // 动画循环
    function loop() {
        // 清空画布
        ctx.clearRect(0, 0, canvas.width, canvas.height);

        // 随机偏移像素数据
        for (let i = 0, n = pixels.data.length; i < n; i += 4) {
            const x = Math.floor(Math.random() * canvas.width);
            const y = Math.floor(Math.random() * canvas.height);
            const pixelIndex = (y * canvas.width + x) * 4;
            pixels.data[pixelIndex]     = pixels.data[i];
            pixels.data[pixelIndex + 1] = pixels.data[i + 1];
            pixels.data[pixelIndex + 2] = pixels.data[i + 2];
            pixels.data[pixelIndex + 3] = 255;
        }

        // 绘制像素数据
        ctx.putImageData(pixels, 0, 0);

        // 请求下一帧
        requestAnimationFrame(loop);
    }

    // 启动动画循环
    loop();
};
    </script>
</body>
</html>